import type { Router } from 'vue-router'
import type { RouteRecordType } from './index'

import { isNavigationFailure } from 'vue-router'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style

import store from '../store/index'
import PATH from './path'
import { getToken } from '@/utils/token-util'
import roleJudge from '@/utils/role-judge'

// 不显示右上角加载图标
NProgress.configure({ showSpinner: false })

// 登录了就不能进了
const redirectPathList = [PATH.login]
// 不登录也可以随便进
const whitePathList = [PATH.login]

export function createRouterGuards(router: Router) {
  router.beforeEach(async (to) => {
    NProgress.start()

    const token = getToken()
    // 没有 token
    if (!token) {
      if (whitePathList.includes(to.path)) {
        return true
      } else {
        let nextPath = PATH.login
        if (!['', '/', ...redirectPathList].includes(to.path)) {
          // 登录的时候会处理 redirect
          nextPath = PATH.login + '?redirect=' + encodeURIComponent(to.fullPath)
        }
        return nextPath
      }
    }

    if (redirectPathList.includes(to.path)) {
      return '/'
    }

    // 如果路由里带了重定向信息，处理重定向。一般可能出现在分享的时候。
    const redirectPath = to.query.redirect as string
    if (redirectPath) {
      return decodeURIComponent(redirectPath)
    }

    // 获取用户信息
    const userStore = store.useUserStore()
    if (!userStore.id) {
      let flag = true
      await userStore.getInfo().catch(() => {
        flag = false
      })
      if (!flag) {
        return '/'
      }
    }

    // 如果已经添加过动态路由，路由通过
    const routeStore = store.useRouteStore()
    if (routeStore.hasDynamicAddedRoute) {
      return true
    }

    const role = roleJudge.getRole()
    // 动态添加可访问路由表
    const accessedRoutes = routeStore.getAccessedRoutes(role)
    accessedRoutes.forEach((item: RouteRecordType) => {
      router.addRoute(item)
    })

    // 进入路由循环，使动态路由生效
    return to.fullPath
  })

  router.afterEach((_to, _, failure) => {
    if (isNavigationFailure(failure)) {
      // eslint-disable-next-line no-console
      console.log('failed navigation', failure)
    }
    NProgress.done()
  })

  router.onError((error) => {
    // eslint-disable-next-line no-console
    console.log('路由错误', error)
    NProgress.done()
  })
}
